package com.hdd.utils.wx;

import com.hdd.utils.DateUtil;
import com.hdd.utils.OSSUtil;
import com.hdd.utils.UUIDGenerator;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.Iterator;

/**
 * @author ;
 * @Description: 图片上传
 * @Date: 2020-07-08 9:54
 **/

@Component
public class WxImageUtil {

    @Autowired
    private WxMiniProgramCheckUtil checkUtil;

    /**
     * 上传图片，保存原图和压缩图片
     *
     * @param fileDirectory 图片存放路径
     * @param request       图片请求
     * @return 图片地址，多个图片用逗号隔开
     */
    public String uploadImage(String fileDirectory, HttpServletRequest request) {
        return uploadImage(fileDirectory, request, 1);
    }

    public String uploadMaterial(String fileDirectory, MultipartFile file) {
        String url = "";
        try {
            url = saveImage(file, fileDirectory, 2);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return url;
    }

    /**
     * 上传头像
     *
     * @param fileDirectory 图片存放路径
     * @param request       图片请求
     * @return 图片地址
     */
    public String uploadHead(String fileDirectory, HttpServletRequest request) {
        return uploadImage(fileDirectory, request, 3);
    }

    public String uploadPainting(MultipartFile file, String fileDirectory){
        String url = "";
        try {
            url = saveImage(file, fileDirectory, 1);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return url;
    }

    public String uploadFile(MultipartFile file, String fileDirectory){
        String url = "";
        if (file != null && file.getOriginalFilename() != null) {
            String filename = file.getOriginalFilename();
            String str = filename.substring(filename.lastIndexOf(".") + 1);
            url = saveFile(fileDirectory, file, str);
        }
        return url;
    }

    /**
     * 将网络图片保存到本地
     *
     * @param savePath 保存的位置
     * @param urlStr   网络图片地址
     * @return 图片地址
     */
    public static String saveImageUrl(String savePath, String urlStr) {
        File tempFile = makeFile(savePath);
        InputStream is = null;
        FileOutputStream os = null;
        FileOutputStream os2 = null;
        try {
            // 构造URL
            URL url = new URL(urlStr);
            // 打开连接
            URLConnection con = url.openConnection();
            // 输入流
            is = con.getInputStream();
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流
            os = new FileOutputStream(tempFile, true);
            StringBuilder path = new StringBuilder(tempFile.getPath());
            os2 = new FileOutputStream(path.insert(path.lastIndexOf("."), "_head").toString(), true);
            // 开始读取
            while ((len = is.read(bs)) != -1) {
                os.write(bs, 0, len);
                os2.write(bs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 完毕，关闭所有链接
            try {
                if (os2 != null) {
                    os2.close();
                }
                if (os != null) {
                    os.close();
                }
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return tempFile.getPath().replace(File.separatorChar, '/');
    }

    /**
     * 保存Base64图片
     *
     * @param str            图片的base64字符串
     * @param filesDirectory 保存的文件夹名
     * @return 图片地址
     */
    public static String saveBase64(String str, String filesDirectory) {
        String url = null;
        try {
            byte[] bytes = new BASE64Decoder().decodeBuffer(str);

            ByteArrayInputStream in = new ByteArrayInputStream(bytes);
            BufferedImage read = ImageIO.read(in);
            in.close();

            String pathUrl = DateUtil.format(new Date(), "yyyy/MM/dd");
            File todayDirectory = new File(filesDirectory, pathUrl);
            if (!todayDirectory.exists()) {
                todayDirectory.mkdirs();
            }
            // 保证文件名称唯一
            String name = UUIDGenerator.generate() + ".jpg";
            File tempFile = new File(todayDirectory, name);
            ImageIO.write(read, "jpg", tempFile);

            StringBuilder builder = new StringBuilder(name);
            File pressFile = new File(todayDirectory, builder.insert(builder.lastIndexOf("."), "_2").toString());
            ImageIO.write(read, "jpg", pressFile);

            url = OSSUtil.uploadMultipartFileToOSS(tempFile);
            OSSUtil.uploadMultipartFileToOSS(pressFile);

            //删除本地
            delImage(tempFile.getPath().replace(File.separatorChar, '/'));
            delImage(pressFile.getPath().replace(File.separatorChar, '/'));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return url;
    }

    /**
     * 删除图片
     * @param path
     * @return
     */
    public static boolean delImage(String path){
        boolean del = false;
        File file = new File(path);
        if (file.exists() && file.isFile()) {
            del = file.delete();
        }
        return del;
    }

    /**
     * 上传图片，保存原图、压缩图片
     *
     * @param fileDirectory 图片存放路径
     * @param request       图片请求
     * @return 图片地址，多个图片用逗号隔开
     */

    private String uploadImage(String fileDirectory, HttpServletRequest request, int type){
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        if (resolver.isMultipart(request)) {
            MultipartRequest req = (MultipartRequest) request;
            // 获取文件表单字段
            Iterator<String> fileds = req.getFileNames();
            StringBuilder picUrl = new StringBuilder();
            // 遍历文件表单字段
            while (fileds.hasNext()) {
                String filed = fileds.next();
                // 根据字段获取到文件
                MultipartFile file = req.getFile(filed);
                if (file == null) {
                    return null;
                }
                try {
                    String url = saveImage(file, fileDirectory, type);
                    if (fileds.hasNext()) {
                        picUrl.append(url).append(",");
                    } else {
                        picUrl.append(url);
                    }
                } catch (Exception e) {
                    return "错误";
                }
            }

            return picUrl.toString();
        }
        return ("请将表单的enctype属性设置为'multipart/form-data'");
    }

    //type ：1 作品上传，审核 2 素材上传，不审核 3 头像上传
    private String saveImage(MultipartFile file, String fileDirectory, int type) throws IOException {
        String url = "";
        if (file != null && file.getOriginalFilename() != null) {
            String filename = file.getOriginalFilename();
            String str = filename.substring(filename.lastIndexOf(".") + 1);
            if ("jpg".equals(str.toLowerCase()) || "png".equals(str.toLowerCase()) || "jpeg".equals(str.toLowerCase())) {
                if (type != 2) {
                    byte[] img = null;
                    if (file.getSize() >= 1024 * 1024) {
                        //压缩图片，审核
                        img = ImageUtil.compressImgToBytes(file.getBytes(), 1, str);
                    }else {
                        img = file.getBytes();
                    }
                //    图片审核
                    WxMiniProgramCheckUtil.CheckResult checkResult = checkUtil.imgSecCheck(img);
                    if (!checkResult.isCompliance()) {
                        return null;
                    }
                }

                String path = saveFile(fileDirectory, file, str);
                String pressPath;

                if (type == 3) {
                    //压缩头像
                    pressPath = ImageUtil.compressImgToString(url, 1, "head");
                } else if (file.getSize() > (100 * 1024)) {
                    //图片压缩
                    pressPath = ImageUtil.compressImgToString(path, 1, "2");
                } else {
                    file.getBytes();
                    pressPath = ImageUtil.savaByte(path, file.getBytes());
                }

                try {
                    url = OSSUtil.uploadMultipartFileToOSS(new File(path));
                    OSSUtil.uploadMultipartFileToOSS(new File(pressPath));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //删除本地
                delImage(path);
                delImage(pressPath);
            }
        }
        return url;
    }

    /**
     * 保存文件到本地
     */
    private static String saveFile(String serverDeployPath, MultipartFile multipartFile, String str) {
        File filesDirectory = new File(serverDeployPath);
        // 文件夹不存在则创建
        if (!filesDirectory.exists()) {
            filesDirectory.mkdirs();
        }
        OutputStream out = null;
        InputStream in = null;
        try {
            // 按天建立文件夹
            Date now = new Date();
            File todayDirectory = new File(filesDirectory, DateUtil.format(now, "yyyy/MM/dd"));
            if (!todayDirectory.exists()) {
                todayDirectory.mkdirs();
            }
            // 保证文件名称唯一
            File tempFile = new File(todayDirectory, UUIDGenerator.generate());
            // 用流的方式进行数据copy
            if ("jpg".equals(str.toLowerCase()) || "png".equals(str.toLowerCase()) || "jpeg".equals(str.toLowerCase())) {
                //是图片，选择性压缩
                if (multipartFile.getSize() > 1024 * 1024) {
                    byte[] bytes = ImageUtil.compressImgToBytes(multipartFile.getBytes(), 1, str);
                    in = new ByteArrayInputStream(bytes);
                } else if (multipartFile.getSize() > 700 * 1024) {
                    byte[] bytes = ImageUtil.compressImgToBytes(multipartFile.getBytes(), 1, str);
                    in = new ByteArrayInputStream(bytes);
                } else {
                    in = multipartFile.getInputStream();
                }
            }else {
                //是文件，不压缩
                in = multipartFile.getInputStream();
            }

//            out = new FileOutputStream(tempFile.getAbsolutePath());
//            IOUtils.copy(in, out);
//            // 释放输出流，以便可以操作临时文件
//            IOUtil.closeQuietly(out);
//            // 计算文件的md5值，文件存在则使用以前的文件
//            String md5FileName = HashUtil.getMd5(tempFile) + getFileSuffix(multipartFile.getOriginalFilename());
//
//            File destMd5File = new File(todayDirectory, md5FileName);
//            synchronized (WxImageUtil.class) {
//                if (destMd5File.exists()) {
//                    tempFile.delete();
//                } else {
//                    tempFile.renameTo(destMd5File);
//                }
//            }
            // 返回相对路径
 //           return destMd5File.getPath().replace(File.separatorChar, '/');
            return null;
        } catch (Exception e) {

            throw new RuntimeException("文件上传失败，请重试！");
        } finally {
//            IOUtil.closeQuietly(out);
//            IOUtil.closeQuietly(in);
        }
    }

    /**
     * 获取文件后缀，例如：index.html，则返回.html
     */
    private static String getFileSuffix(String fileName) {
        if (StringUtils.isBlank(fileName)) {
            return null;
        }
        int index = fileName.lastIndexOf(".");
        return fileName.substring(index);
    }

    private static File makeFile(String serverDeployPath) {
        File filesDirectory = new File(serverDeployPath);
        // 文件夹不存在则创建
        if (!filesDirectory.exists()) {
            filesDirectory.mkdirs();
        }
        // 按天建立文件夹
        Date now = new Date();
        File todayDirectory = new File(filesDirectory, DateUtil.format(now, "yyyy") + "/" + DateUtil.format(now, "MM"));
        if (!todayDirectory.exists()) {
            todayDirectory.mkdirs();
        }
        // 保证文件名称唯一
        return new File(todayDirectory, UUIDGenerator.generate() + ".jpg");
    }

    public static void main(String[] args) throws IOException {
        File file = new File("d:\\tom.jpg");
        BufferedImage read = ImageIO.read(file);
//        String s = saveImageUrl("F:\\test", "https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLG76o5uicRh499sv66AzVfKqRRY1Ernb0evLk9EloOpJzrtcAD8p9PfJ3BTLW2HAkVKpicTicaxEjng/132");
//        System.out.println(s);
        byte[] bytes = ImageUtil.compressImgToBytes(ImageUtil.imageToBytes(read, "png"), 0.5, "png");
        String s = ImageUtil.savaByte("D:\\0ad1e58a86ae9c8976514dbdfc0949aa.png",bytes);
        System.out.println(s);
    }
}